/**
 * Copyright (C) 2010 Sergey Grigoriev <s.a.grigoriev@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.gmf.test

import org.apache.commons.io.IOUtils
import org.apache.mina.core.service.IoHandlerAdapter
import org.apache.mina.core.session.IoSession
import org.apache.commons.lang.StringUtils
import org.apache.mina.core.session.IdleStatus
import org.apache.log4j.Logger

/**
 * Handles socket events from continuous integration listener which runs in flash player
 */
class XmlSocketListener extends IoHandlerAdapter {

  private final String SOCKET_POLICY_FILE_REQUEST = "<policy-file-request/>"

  private final String START_OF_TEST_RUN_ACK = "<startOfTestRunAck/>"

  private final String END_OF_TEST_RUN = "<endOfTestRun/>"

  private final String END_OF_TEST_ACK = "<endOfTestRunAck/>"


  private final Logger l4j = Logger.getLogger(this.getClass())

  StringBuilder content

  boolean flexUnitSessionStarted

  def void sessionCreated(IoSession session) {
    content = new StringBuilder()
  }

  def void messageReceived(IoSession session, Object message) {
    String request = message.toString()
    l4j.debug("received data from flash player: $request ")

    if (request.equalsIgnoreCase(SOCKET_POLICY_FILE_REQUEST)) {
      InputStream is = IOUtils.getResourceAsStream("/crossdomain.xml")
      try {
        session.write(is.getText('utf8'))
      } finally {
        is.close()
      }
    } else if (END_OF_TEST_RUN.equalsIgnoreCase(request)) {
      session.write(END_OF_TEST_ACK)
    } else if (StringUtils.isNotBlank(request)) {
      content.append(request).append("\n")
    }
  }

  def synchronized void sessionClosed(IoSession session) {
    notify()
  }

  /**
   * Wait for all the tests to finish
   */
  def synchronized waitForAllTestsToComplete() {
    wait()
  }

  def void sessionIdle(IoSession session, IdleStatus status) {
    if (!flexUnitSessionStarted) {
      flexUnitSessionStarted = true;
      session.write(START_OF_TEST_RUN_ACK)
    }
  }
}